package com.resource.manager.search;

import cn.hutool.core.util.ObjectUtil;
import com.resource.manager.search.vo.FileType;
import com.resource.manager.search.vo.FileTypeInstance;
import com.resource.manager.ui.CustButton;
import com.resource.manager.ui.ImagePanel;
import com.resource.manager.util.SwingUtil;
import lombok.Data;
import lombok.SneakyThrows;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;

/**
 * 新建查询窗口
 */
public class NewSearchWindow extends JFrame {

    private static final Integer TAIL = 120;

    @SneakyThrows
    public NewSearchWindow() {
        super("新建查询实例");
        //设置图标
        SwingUtil.setTitleIco(this);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //获取屏幕大小
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        double maxWidth = screenSize.getWidth();
        double maxHeight = screenSize.getHeight();
        //设置窗口大小为屏幕大小一半,居中显示
        setSize((int) (maxWidth / 1.5), (int) (maxHeight / 1.5));
        setLocationRelativeTo(null);
        //设置背景色为白色
        getContentPane().setBackground(Color.WHITE);
        this.setLayout(null);

        //设置查询文件类型面板
        JScrollPane top = new JScrollPane();
        top.setBounds(0, 0, this.getWidth(), this.getHeight() - TAIL);
        top.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        top.getVerticalScrollBar().setUnitIncrement(30); //

        SearchFileTypePanel panel = new SearchFileTypePanel(top);
        top.setViewportView(panel);
        //设置滚动条可滚动
        top.setEnabled(true);

        this.add(top);

        //设置控制面板,添加控制按钮
        ControlFileTypePanel controlFileTypePanel = new ControlFileTypePanel(this, panel, 0, this.getHeight() - TAIL, this.getWidth(), TAIL);
        this.add(controlFileTypePanel);


        //监听窗口缩放
        this.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
                top.setBounds(0, 0, getWidth(), getHeight() - TAIL);
                panel.setBounds(0, 0, getWidth(), getHeight() - TAIL);
                controlFileTypePanel.setBounds(0, getHeight() - TAIL, getWidth(), TAIL);
            }
        });
        setVisible(true);
    }

    /**
     * 文件类型控制面板
     */
    @Data
    public static class ControlFileTypePanel extends JPanel {

        NewSearchWindow searchWindow;
        protected SearchFileTypePanel searchFileTypePanel;
        protected List<CustButton> buttons = new ArrayList<>();
        protected JLabel pathLabel;
        protected CustButton addPathButton;
        protected CustButton addFileTypeButton;
        protected CustButton importFileTypeButton;

        public ControlFileTypePanel(NewSearchWindow searchWindow, SearchFileTypePanel searchFileTypePanel, int x, int y, int width, int height) {
            super();
            this.searchWindow = searchWindow;
            this.searchFileTypePanel = searchFileTypePanel;
            this.setLayout(null);
            this.setBounds(x, y, width, height);

            initControlContent();
            //监听窗口缩放
            this.addComponentListener(new ComponentAdapter() {
                @Override
                public void componentResized(ComponentEvent e) {
                    initControlContent();
                }
            });

        }

        private void initControlContent() {
            for (CustButton button : buttons) {
                this.remove(button);
            }
            if (!ObjectUtil.isEmpty(addPathButton)) {
                this.remove(addPathButton);
            }
            if (!ObjectUtil.isEmpty(pathLabel)) {
                this.remove(pathLabel);
            }
            buttons.clear();
            //添加path
            pathLabel = new JLabel("E:\\");
            //根据字体像素长度设置label宽度
            //根据font像素获取字体占用长度
            int textWidth = SwingUtil.getFontWidth(getGraphics(), new Font("微软雅黑", Font.PLAIN, 12), pathLabel.getText());
            pathLabel.setBounds(getWidth() - (320 + textWidth), 25, textWidth, 30);
            pathLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
            this.add(pathLabel);

            addFileTypeButton = new CustButton("添加已有类型");
            addFileTypeButton.setBounds(20, 20, 140, 40);
            addFileTypeButton.setFont(new Font("微软雅黑", Font.PLAIN, 15));
            addFileTypeButton.addActionListener(e -> {
                JDialog dialog = new JDialog(searchWindow);
                dialog.setTitle("添加已有类型");
                SwingUtil.setTitleIco(dialog);
                dialog.setResizable(false);
                dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                dialog.setBounds(searchWindow.getX() + 100, this.getY() - 400, 400, 500);
                dialog.setLayout(null);
                dialog.getContentPane().setBackground(Color.WHITE);
                dialog.setBackground(Color.WHITE);
                dialog.setVisible(true);
                //设置不可操作其他窗口
                dialog.setModal(true);

                List<FileType> fileTypes = FileType.buildDefaultFileType();

                List<FileType> exitTypes = searchFileTypePanel.getTypeInstance().getFileTypes();
                int y = 10;
                Map<JCheckBox, FileType> boxList = new HashMap<>();
                for (FileType fileType : fileTypes) {
                    JPanel panel = new JPanel();
                    panel.setBackground(Color.WHITE);
                    panel.setBounds(20, y, 300, 40);
                    panel.setLayout(null);

                    //复选框
                    JCheckBox checkBox = new JCheckBox();
                    checkBox.setBounds(5, 8, 20, 20);
                    checkBox.setBackground(Color.WHITE);
                    if (exitTypes.stream().anyMatch(e1 -> e1.getName().equals(fileType.getName()))) {
                        checkBox.setSelected(true);
                    }
                    checkBox.addActionListener(e1 -> {
                        if (checkBox.isSelected()) {
                            if (!exitTypes.stream().anyMatch(e2 -> e2.getName().equals(fileType.getName()))) {
                                //不存在的情况下,添加
                                exitTypes.add(fileType);
                            }
                        } else {
                            exitTypes.removeIf(e2 -> e2.getName().equals(fileType.getName()));
                        }
                    });
                    boxList.put(checkBox,fileType);
                    panel.add(checkBox);

                    ImagePanel imagePanel = new ImagePanel(fileType.getIco());
                    imagePanel.setBounds(40, 5, 30, 30);
                    panel.add(imagePanel);
                    JLabel label = new JLabel(fileType.getName());
                    label.setBounds(100, 5, 180, 30);
                    label.setFont(new Font("微软雅黑", Font.PLAIN, 15));
                    panel.add(label);

                    y += 40;
                    dialog.add(panel);
                }
                //复选框
                JCheckBox allCheck = new JCheckBox();
                allCheck.setBounds(25, y+10, 20, 20);
                allCheck.setBackground(Color.WHITE);
                boolean exitNoCheck = boxList.keySet().stream().anyMatch(b -> !b.isSelected());
                if(!exitNoCheck){
                    allCheck.setSelected(true);
                }
                allCheck.addActionListener(e1 -> {
                    if (allCheck.isSelected()) {
                        boxList.forEach((k,v)->{
                            k.setSelected(true);
                            if (!exitTypes.stream().anyMatch(e2 -> e2.getName().equals(v.getName()))) {
                                //不存在的情况下,添加
                                exitTypes.add(v);
                            }
                        });
                    }else{
                        boxList.forEach((k,v)->{
                            k.setSelected(false);
                            exitTypes.clear();
                        });
                    }
                });
                dialog.add(allCheck);
                JLabel label = new JLabel("全选");
                label.setBounds(60, y + 5, 100, 30);
                label.setFont(new Font("微软雅黑", Font.PLAIN, 15));
                dialog.add(label);

                CustButton confirm = new CustButton("添加");
                confirm.setBounds(280, y + 10, 80, 30);
                confirm.addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        searchFileTypePanel.getTypeInstance().setFileTypes(exitTypes);
                        searchFileTypePanel.initFileType(searchFileTypePanel.getWidth());
                        searchFileTypePanel.revalidate();
                        searchFileTypePanel.repaint();
                        dialog.dispose();
                    }
                });
                dialog.add(confirm);
            });
            this.add(addFileTypeButton);

            importFileTypeButton = new CustButton("导入新类型");
            importFileTypeButton.setBounds(180, 20, 120, 40);
            importFileTypeButton.setFont(new Font("微软雅黑", Font.PLAIN, 15));
            importFileTypeButton.addActionListener(e -> {
                JDialog dialog = new JDialog(searchWindow);
                dialog.setTitle("导入新类型");
                SwingUtil.setTitleIco(dialog);
                dialog.setResizable(false);
                dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                dialog.setBounds(searchWindow.getX() + 100, this.getY() - 300, 400, 300);
                dialog.setLayout(null);
                dialog.getContentPane().setBackground(Color.WHITE);
                dialog.setBackground(Color.WHITE);
                dialog.setVisible(true);
                dialog.setModal(true);

                JLabel typeLable = new JLabel();
                typeLable.setText("类型名称: ");
                typeLable.setBounds(20, 20, 80, 30);
                typeLable.setFont(new Font("微软雅黑", Font.PLAIN, 15));
                dialog.add(typeLable);

                JTextField typeName = new JTextField();
                typeName.setBounds(100, 20, 250, 30);
                //设置灰色边框
                typeName.setBorder(BorderFactory.createLineBorder(Color.GRAY));
                typeName.setFont(new Font("微软雅黑", Font.PLAIN, 15));
                dialog.add(typeName);

                JLabel suffixLable = new JLabel();
                suffixLable.setText("文件后缀: ");
                suffixLable.setBounds(20, 60, 80, 30);
                suffixLable.setFont(new Font("微软雅黑", Font.PLAIN, 15));
                dialog.add(suffixLable);

                JTextArea suffix = new JTextArea();
                suffix.setBounds(100, 60, 250, 120);
                //设置滚动条
                suffix.setWrapStyleWord(true);
                suffix.setLineWrap(true);
                //设置灰色边框
                suffix.setBorder(BorderFactory.createLineBorder(Color.GRAY));
                suffix.setFont(new Font("微软雅黑", Font.PLAIN, 15));
                dialog.add(suffix);

                CustButton confirm = new CustButton("确定");
                confirm.setBounds(280, 220, 80, 30);
                confirm.addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        String text = typeName.getText();
                        if (text.isEmpty()) {
                            JOptionPane.showMessageDialog(dialog, "请输入类型名称");
                            return;
                        }
                        List<FileType> exitTypes = searchFileTypePanel.getTypeInstance().getFileTypes();
                        if (exitTypes.stream().anyMatch(e1 -> e1.getName().equals(text))) {
                            JOptionPane.showMessageDialog(dialog, "类型名称已存在");
                            return;
                        }
                        //suffix
                        String suffixText = suffix.getText();
                        if (ObjectUtil.isEmpty(suffixText)) {
                            JOptionPane.showMessageDialog(dialog, "请输入文件后缀");
                            return;
                        }
                        List<String> suffixList = Arrays.stream(suffixText.split(",")).map(String::trim).toList();
                        FileType fileType = new FileType().setName(typeName.getText()).setIco("img/no.png").setSort(1).setSuffix(suffixList);
                        fileType.setId(UUID.randomUUID().toString());
                        searchFileTypePanel.getTypeInstance().getFileTypes().add(fileType);
                        searchFileTypePanel.initFileType(searchFileTypePanel.getWidth());
                        searchFileTypePanel.revalidate();
                        searchFileTypePanel.repaint();
                        dialog.dispose();
                    }
                });
                dialog.add(confirm);
            });
            this.add(importFileTypeButton);


            //添加pathButton
            addPathButton = new CustButton("请选择");
            addPathButton.setBounds(getWidth() - 300, 20, 120, 40);
            addPathButton.setFont(new Font("微软雅黑", Font.PLAIN, 15));
            addPathButton.addActionListener(e -> {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                chooser.showDialog(new JLabel(), "选择文件夹");
                if (chooser.getSelectedFile() != null) {
                    pathLabel.setText(chooser.getSelectedFile().getAbsolutePath());
                    int newTextWidth = SwingUtil.getFontWidth(getGraphics(), new Font("微软雅黑", Font.PLAIN, 12), pathLabel.getText());
                    pathLabel.setBounds(getWidth() - (320 + newTextWidth), 25, newTextWidth, 30);
                    System.out.println("选择文件夹: " + chooser.getSelectedFile().getAbsolutePath());
                }
            });
            this.add(addPathButton);

            //添加按钮进度
            CustButton createSearch = new CustButton("创建查询");
            createSearch.setBounds(getWidth() - 160, 20, 120, 40);
            createSearch.setFont(new Font("微软雅黑", Font.PLAIN, 15));
            createSearch.addActionListener(e -> {
                //创建查询
                if (ObjectUtil.isEmpty(searchFileTypePanel.getTypeInstance().getFileTypes())) {
                    JOptionPane.showMessageDialog(searchWindow, "请选择文件类型", "提示", JOptionPane.WARNING_MESSAGE);
                    return;
                }
                new SearchScheFrame(searchFileTypePanel, this);
            });
            buttons.add(createSearch);
            this.add(createSearch);
            this.repaint();
        }
    }

    /**
     * 文件类型展示面板
     */
    @Data
    public static class SearchFileTypePanel extends JPanel {

        protected List<FileType> fileTypes = new ArrayList<>();

        protected JScrollPane top;

        protected List<JPanel> fileTypePanels = new ArrayList<>();

        protected FileTypeInstance typeInstance;

        public SearchFileTypePanel(JScrollPane top) {
            super();
            this.setLayout(null);
            this.top = top;
            this.setBackground(Color.WHITE);
            this.setSize(top.getWidth(), top.getHeight());
            typeInstance = FileTypeInstance.build(getWidth());
            initFileType(getWidth());

            //监听窗口缩放
            this.addComponentListener(new ComponentAdapter() {
                @Override
                public void componentResized(ComponentEvent e) {
                    initFileType(getWidth());
                }
            });
        }

        @SneakyThrows
        @Override
        public void paint(Graphics g) {
            super.paint(g);
        }

        private void initFileType(int width) {
            //清理面板中的面板
            for (JPanel fileTypePanel : fileTypePanels) {
                this.remove(fileTypePanel);
            }
            this.fileTypePanels.clear();
            fileTypes = typeInstance.getFileTypes(width);
            int height = getHeight();
            int maxHeight = height;
            for (FileType fileType : fileTypes) {
                JPanel fileTypePanel = new JPanel();
                fileTypePanel.setLayout(null);
                fileTypePanel.setBackground(Color.WHITE);
//                fileTypePanel.setBackground(Color.RED);
                fileTypePanel.setBounds(fileType.getX(), fileType.getY(), fileType.getWidth(), fileType.getHeight());

                ImagePanel typePanel = new ImagePanel(fileType.getIco());
                typePanel.setBounds(15, 15, fileType.getWidth() - 30, fileType.getHeight() - 50);
                typePanel.setVisible(true);
                fileTypePanel.add(typePanel);

                JLabel nameLabel = new JLabel(fileType.getName());
                nameLabel.setBounds(0, fileType.getHeight() - 25, fileType.getWidth(), 20);
                nameLabel.setFont(new Font("微软雅黑", Font.PLAIN, 13));
                nameLabel.setHorizontalAlignment(SwingConstants.CENTER);
                nameLabel.setForeground(Color.BLACK);
                fileTypePanel.add(nameLabel);

                fileTypePanel.setVisible(true);
                if (fileTypePanel.getY() + fileType.getHeight() > height) {
                    maxHeight = fileTypePanel.getY() + fileType.getHeight();
                }

                //添加右键菜单
                JPopupMenu popupMenu = new JPopupMenu();
                JMenuItem menuItem = new JMenuItem("删除");
                menuItem.addActionListener(e -> {
                    typeInstance.removeFileType(fileType.getId());
                    initFileType(width);
                    this.top.revalidate();
                    this.revalidate();
                    this.repaint();
                });
                popupMenu.add(menuItem);
                fileTypePanel.setComponentPopupMenu(popupMenu);

                fileTypePanels.add(fileTypePanel);
                this.add(fileTypePanel);
            }
            if (maxHeight > height) {
                this.setPreferredSize(new Dimension(width, maxHeight + 20));
                top.repaint();
            }
        }

    }

}
